﻿using System;
using System.Collections.ObjectModel;
using System.Linq;
using dIRca.Data.Settings;

namespace dIRca.Data.Services
{
    public class LastConnectionService : ILastConnectionService, IDisposable
    {
        #region Properties
        private DatabaseService _storageService;

        private readonly object _sync = new object();
        private bool _isLoaded;

        private int _maxItems;

        private ObservableCollection<LastConnection> _itemsList;
        public ReadOnlyObservableCollection<LastConnection> ItemsList
        {
            get
            {
                if (!_isLoaded)
                    LoadFromStorage();

                return new ReadOnlyObservableCollection<LastConnection>(_itemsList);
            }
        }

        #endregion

        public LastConnectionService(DatabaseService storageService, int maxItems)
        {
            _storageService = storageService;
            _maxItems = maxItems;
            if (!_storageService.IsRunning)
            {
                _storageService.Start();
                _storageService.Starting();
            }
        }

        private void LoadFromStorage()
        {
            if (_isLoaded)
                return;

            lock (_sync)
            {
                if (_isLoaded)
                    return;

                _itemsList = new ObservableCollection<LastConnection>();

                var records = _storageService.Database.Query<LastConnection, int>().ToList();
                if (records == null || records.Count == 0)
                {
                    //_logger.Write("LastConnectionService: No recent connections");
                }
                else
                {
                    foreach (var record in records)
                    {
                        //_logger.Write("LastConnectionService: Loading Property, hash code - " + record.GetHashCode());
                        if (record.LazyValue.Value != null)
                            _itemsList.Add(record.LazyValue.Value);
                    }
                }

                _isLoaded = true;
            }
        }

        public void Add(LastConnection property)
        {
            if (property == null)
                return;

            if (!_isLoaded)
                LoadFromStorage();

            if (_itemsList.Contains(property))
                return;

            _itemsList.Add(property);

            // We only want to prune the list when we add, not during deletions
            _itemsList.Take(_maxItems).ToList().ForEach(item =>
            {
                _storageService.Database.Save(item);
            });
            _storageService.Database.Flush();
        }

        public void Delete(LastConnection property)
        {
            if (property == null)
                return;
            if (!_isLoaded)
                LoadFromStorage();

            if (!_itemsList.Contains(property))
                return;

            _itemsList.Remove(property);
            _storageService.Database.Delete<LastConnection>(property);
            _storageService.Database.Flush();
        }

        public void Dispose()
        {
            if (_storageService != null)
            {
                _storageService.Dispose();
                _storageService = null;
            }
        }
    }
}
